package cn.itcast.service.cargo.impl;

import cn.itcast.dao.cargo.*;
import cn.itcast.domain.cargo.*;
import cn.itcast.service.cargo.ExportService;
import cn.itcast.vo.ExportProductResult;
import cn.itcast.vo.ExportResult;
import com.alibaba.dubbo.config.annotation.Service;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;

/**
 * @author LT
 * @version 1.0.0
 * @ClassName ExportServiceImpl.java
 * @Description TODO
 * @createTime 2020年04月05日 21:24:00
 */
@Service
public class ExportServiceImpl implements ExportService {

    @Autowired
    private ExportDao exportDao;

    @Autowired
    private ContractDao contractDao;

    @Autowired
    private ContractProductDao contractProductDao;

    @Autowired
    private ExportProductDao exportProductDao;

    @Autowired
    private ExtCproductDao extCproductDao;

    @Autowired
    private ExtEproductDao extEproductDao;

    /*
    查找报运单列表分页页面
     */
    @Override
    public PageInfo<Export> findByPage(ExportExample exportExample, int pageNum, int pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        //查找对应的数据
        List<Export> exportList = exportDao.selectByExample(exportExample);
        return new PageInfo<>(exportList);
    }

    /**
     * 根据海关返回的结果，把结果的信息同步的我们的数据库中
     *
     * @param exportResult
     */
    @Override
    public void updateByResult(ExportResult exportResult) {
        // 1.找到报运单
        String exportId = exportResult.getExportId();
        Export export = exportDao.selectByPrimaryKey(exportId);
        // 2.更新报运单的状态
        export.setState(exportResult.getState());
        // 3.更新报运单的备注信息
        export.setRemark(exportResult.getRemark());
        // 4.更新报运单
        exportDao.updateByPrimaryKeySelective(export);
        // 5.找到所有的商品，给商品补全税
        Set<ExportProductResult> products = exportResult.getProducts();
        for (ExportProductResult productResult : products) {
            // 根据商品的id，查找到对应的商品，然后给商品设置税
            String exportProductId = productResult.getExportProductId();
            ExportProduct exportProduct = exportProductDao.selectByPrimaryKey(exportProductId);
            exportProduct.setTax(productResult.getTax());
            exportProductDao.updateByPrimaryKeySelective(exportProduct);
        }
    }

    //查找所有的报运单
    @Override
    public List<Export> findAll(ExportExample exportExample) {
        return exportDao.selectByExample(exportExample);
    }

    //根据主键查找
    @Override
    public Export findById(String id) {
        return exportDao.selectByPrimaryKey(id);
    }

    /**
     * 修改报运单
     *
     * @param export
     */
    @Override
    public void save(Export export) {
        export.setId(UUID.randomUUID().toString());
        //注意： 因为创建时间与更新时间字段不能为空，所以我们在插入数据的时候需要补充这两个字段的值
        // export.setCreateTime(new Date());
        // export.setUpdateTime(new Date());
        // 1）往报运单表插入一条记录
        // 1.1 插入之前，要先把报运单的数据补全。
        export.setInputDate(new Date());
        // 1.2 找到所有的购销合同合同id
        String[] contractIds = export.getContractIds().split(",");
        // 1.3 根据购销合同的id查找到所有的购销合同
        ContractExample contractExample = new ContractExample();
        contractExample.createCriteria().andIdIn(Arrays.asList(contractIds));
        List<Contract> contractList = contractDao.selectByExample(contractExample);
        // 1.4 遍历所有的购销合同，拼接合同号
        String contractNos = "";
        // 定义一个变量报运所有的购销合同货物的种类数量
        int totalProNum = 0;
        // 定义一个变量报运所有的购销合同附件的种类数量
        int totalExtNum = 0;
        for (Contract contract : contractList) {
            // 拼接合同号
            contractNos += contract.getContractNo() + " ";
            // 统计所有货物种类数量
            totalProNum += contract.getProNum();
            // 统计所有附件种类数量
            totalExtNum += contract.getExtNum();
            // 2）报运单下面的购销合同的状态从1改为2 ,
            // 购销合同的状态：
            // 0（草稿，草稿状态下的合同不能申请报运）
            // 1(允许被报运了) ，
            // 2（已经生成报运单合同））
            contract.setState(2);
            contractDao.updateByPrimaryKeySelective(contract);
        }
        // 给报运设置合同号
        export.setCustomerContract(contractNos);
        // 刚刚生成报运单是出于草稿状态
        export.setState(0);
        export.setProNum(totalProNum);
        export.setExtNum(totalExtNum);
        export.setCreateTime(new Date());
        export.setUpdateTime(new Date());

        // 插入报运单
        exportDao.insertSelective(export);
        // 3）把购销合同下的所有货物数据导入到报运单的商品表中
        ContractProductExample contractProductExample = new ContractProductExample();
        contractProductExample.createCriteria().andContractIdIn(Arrays.asList(contractIds));
        // 根据购销合同的id，查找对应的货物
        List<ContractProduct> contractProducts = contractProductDao.selectByExample(contractProductExample);
        // 使用一个map集合保存购销合同货物的id与报运商品的id
        Map<String, String> map = new HashMap<>();
        // 遍历货物，把购销合同货物的数据迁移到报运商品表中，一个购销合同的货物就对应一个报运商品
        for (ContractProduct contractProduct : contractProducts) {
            ExportProduct exportProduct = new ExportProduct();
            // 根据ContractProduct 和 ExportProduct的字段名匹配，然后进行数据的拷贝
            BeanUtils.copyProperties(contractProduct, exportProduct);
            // 设置id
            exportProduct.setId(UUID.randomUUID().toString());
            // 设置报运的视频所属的报运单
            exportProduct.setExportId(export.getId());
            // 键：购销合同货物表的id,值：报运商品表的Id
            map.put(contractProduct.getId(), exportProduct.getId());   // contractProduct.getId()=获取报运货物的id,exportProduct.getId()=报运商品的id
            // 把报运商品插入数据库中
            exportProductDao.insertSelective(exportProduct);
        }

        // 4）购销合同下的所有的附件数据导入到 报运商品附件表中
        // 根据购销合同的id，找到对应附件数据
        ExtCproductExample extCproductExample = new ExtCproductExample();
        extCproductExample.createCriteria().andContractIdIn(Arrays.asList(contractIds));
        List<ExtCproduct> extCproductList = extCproductDao.selectByExample(extCproductExample);
        if (extCproductList != null) {
            //遍历所有的附件，把购销合同附件数据迁移到报运附件表中
            for (ExtCproduct extCproduct : extCproductList) {  // 附件有两个外键， contractId，contractProductId.
                ExtEproduct extEproduct = new ExtEproduct(); // 报运的附件
                // 拷贝数据
                BeanUtils.copyProperties(extCproduct, extEproduct);
                // 设置id
                extEproduct.setId(UUID.randomUUID().toString());
                // 设置所属报运单
                extEproduct.setExportId(export.getId());
                // 设置所属的报运商品
                extEproduct.setExportProductId(map.get(extCproduct.getContractProductId()));
                // 插入附件
                extEproductDao.insertSelective(extEproduct);
            }
        }
    }


    //更新报运单
    @Override
    public void update(Export export) {
        // 1.更新报运单
        export.setUpdateTime(new Date());
        exportDao.updateByPrimaryKeySelective(export);

        // 2.取出所有的报运单下的所有商品然后更新
        List<ExportProduct> exportProducts = export.getExportProducts();
        if (exportProducts != null) {
            for (ExportProduct exportProduct : exportProducts) {
                exportProductDao.updateByPrimaryKeySelective(exportProduct);
            }
        }
    }

    //删除 根据报运单的id删除
    @Override
    public void delete(String id) {
        exportDao.deleteByPrimaryKey(id);
    }

}
